#pragma once
#include <iostream>
#include <sys/epoll.h>
#include "Log.hpp"
#include "Err.hpp"
#include <cstring>
#include <cerrno>

const static int default_dpfd = -1;
const static int gsize = 128;

class Epoller
{
public:
    Epoller() : epfd_(default_dpfd)
    {
    }

    // 创建epoll模型(底层)
    void Create()
    {
        epfd_ = epoll_create(gsize);
        if (epfd_ < 0)
        {
            logMessage(Fatal, "Create Epoller Error %d %s", errno, strerror(errno));
            exit(CREATE_EPOLLER_ERR);
        }
        
    }

    bool AddModEvent(int fd, uint32_t events, int op)
    {
        //op:EPOLL_CTL_ADD/EPOLL_CTL_MOD

        struct epoll_event ev;
        ev.data.fd = fd;
        ev.events = events;

        int n = epoll_ctl(epfd_, op, fd, &ev);
        if(n < 0)
        {
            logMessage(Fatal,"epoll_ctl error %d %s",errno,strerror(errno));
            return false;
        }

        return true;
    }

    bool DelEvent(int fd)
    {
        //epoll操作fd时，要求fd必须合法
        return epoll_ctl(epfd_,EPOLL_CTL_DEL,fd,nullptr) == 0;
    }

    int Wait(struct epoll_event* revs,int max_num,int timeout)
    {
        return epoll_wait(epfd_,revs,max_num,timeout);
    }

    void Close()
    {
        if(epfd_ != default_dpfd)
            close(epfd_);
    }

    int Fd()
    {
        return epfd_;
    }

private:
    int epfd_;
};